#include <func.h>
#define num 10
typedef struct queue_s
{
    int front;
    int rear;
    int elem[num];
    int size;
} queue_t;
typedef struct shardRes_s
{
    queue_t queue;
    pthread_mutex_t Mutex;
    pthread_cond_t cond;
} shardRes_t;

int cnt = 0;

void *produce(void *arg)
{
    shardRes_t *shard = (shardRes_t *)arg;
    printf("=======================生产者=============\n");
    while (1)
    {
        pthread_mutex_lock(&shard->Mutex);
        if (shard->queue.size == 10)
        {
            pthread_cond_wait(&shard->cond, &shard->Mutex);
        }
        shard->queue.elem[shard->queue.rear] = cnt++;
        shard->queue.rear = (shard->queue.rear + 1) % num;
        ++shard->queue.size;
        printf("produce size= %d,front rear %d %d,front= %d,rear= %d",
               shard->queue.size,shard->queue.front,
               shard->queue.rear,
               shard->queue.elem[shard->queue.front],
               shard->queue.elem[(shard->queue.rear - 1 + num) % num]);
        if (shard->queue.size == 1)
        {
            pthread_cond_signal(&shard->cond);
        }
        pthread_mutex_unlock(&shard->Mutex);
        usleep(500000);
    }
}
    void *consum(void *arg)
    {
        shardRes_t *pshare = (shardRes_t *)arg;
        printf("================================消费者================\n");
        while (1)
        {
            pthread_mutex_lock(&pshare->Mutex);
            if (pshare->queue.size == 0)
            {
                pthread_cond_wait(&pshare->cond, &pshare->Mutex);
            }
            pshare->queue.front = (pshare->queue.front + 1) % num;
            --pshare->queue.size;
            printf("consumer size= %d,front rear %d %d,front= %d,rear= %d \n",
                   pshare->queue.size,
                   pshare->queue.front,
                   pshare->queue.rear,
                   pshare->queue.elem[pshare->queue.front],
                   pshare->queue.elem[(pshare->queue.rear - 1 + num) % num]);
            if (pshare->queue.size == 9)
            {
                pthread_cond_signal(&pshare->cond);
            }

            pthread_mutex_unlock(&pshare->Mutex);
            sleep(1);
        }
    }

    int main()
    {

        printf("=================主线程===================\n");
        shardRes_t shareRes;
        bzero(&shareRes.queue, sizeof(shareRes.queue));
        printf("produce size= %d,front rear %d %d,front= %d,rear= %d\n",
               shareRes.queue.size,shareRes.queue.front,
                   shareRes.queue.rear,
               shareRes.queue.elem[shareRes.queue.front],
               shareRes.queue.elem[(shareRes.queue.rear - 1 + num) % num]);
        
        pthread_t tid1, tid2;
        pthread_create(&tid1, NULL, produce, (void *)&shareRes);
        pthread_create(&tid2, NULL, consum, (void *)&shareRes);
        
        pthread_mutex_init(&shareRes.Mutex, NULL);
        pthread_cond_init(&shareRes.cond, NULL);

        pthread_join(tid1, NULL);
        pthread_join(tid2, NULL);
        pthread_mutex_destroy(&shareRes.Mutex);
        pthread_cond_destroy(&shareRes.cond);
        return 0;
    }